/*
 * Copyright 2011 OpenWAF.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.openwaf.client.ui.widget;

import com.openwaf.client.core.Window;
import com.openwaf.client.dom.DivElement;
import com.openwaf.client.event.EventManager;
import com.openwaf.client.event.HandlerRegistration;
import com.openwaf.client.event.dom.MouseDownEvent;
import com.openwaf.client.event.dom.MouseDownHandler;
import com.openwaf.client.event.dom.MouseMoveEvent;
import com.openwaf.client.event.dom.MouseMoveHandler;
import com.openwaf.client.event.dom.MouseUpEvent;
import com.openwaf.client.event.dom.MouseUpHandler;
import com.openwaf.client.event.logical.ChangeEndEvent;
import com.openwaf.client.event.logical.ChangeEndHandler;
import com.openwaf.client.event.logical.ChangeEvent;
import com.openwaf.client.event.logical.ChangeHandler;
import com.openwaf.client.event.logical.ChangeStartEvent;
import com.openwaf.client.event.logical.ChangeStartHandler;
import com.openwaf.client.event.logical.HasChangeEndHandlers;
import com.openwaf.client.event.logical.HasChangeHandlers;
import com.openwaf.client.event.logical.HasChangeStartHandlers;
import com.openwaf.client.ui.UIControl;
import com.openwaf.client.ui.annotation.ViewElement;
import com.openwaf.client.event.Event;

public class VerticalSlider  extends UIControl implements  HasChangeHandlers,HasChangeStartHandlers,HasChangeEndHandlers{

    public HandlerRegistration addChangeHandler(final ChangeHandler handler) {
        if(eventManager==null){
            eventManager=new EventManager();
        }
        eventManager.addEventHandler(ChangeEvent.NAME, handler);
        return new HandlerRegistration() {
            public void removeHandler() {
                eventManager.removeEventHandler(ChangeEvent.NAME, handler);
            }
        };
    }
    public HandlerRegistration addChangeStartHandler(final ChangeStartHandler handler){
        if(eventManager==null){
            eventManager=new EventManager();
        }
        eventManager.addEventHandler(ChangeStartEvent.NAME, handler);
        return new HandlerRegistration() {
            public void removeHandler() {
                eventManager.removeEventHandler(ChangeStartEvent.NAME, handler);
            }
        };
    }
    public HandlerRegistration addChangeEndHandler(final ChangeEndHandler handler){
        if(eventManager==null){
            eventManager=new EventManager();
        }
        eventManager.addEventHandler(ChangeEndEvent.NAME, handler);
        return new HandlerRegistration() {
            public void removeHandler() {
                eventManager.removeEventHandler(ChangeEndEvent.NAME, handler);
            }
        };
    }
    @Override
    public void fireEvent(Event<?> event) {
        if (eventManager != null) {
            if (event instanceof ChangeEvent) {
                eventManager.fireEvent(ChangeEvent.NAME, event);
                return;
            }
            if (event instanceof ChangeEndEvent) {
                eventManager.fireEvent(ChangeEndEvent.NAME, event);
                return;
            }
            if (event instanceof ChangeStartEvent) {
                eventManager.fireEvent(ChangeStartEvent.NAME, event);
                return;
            }
        }
        super.fireEvent(event);
    }

    @ViewElement
    private DivElement divContainer;
    @ViewElement
    private DivElement divThumb;
    private HandlerRegistration  mousemoveHandleReg;
    private HandlerRegistration  mouseupHandleReg;
    private EventManager eventManager;
    private int first_y;
    private float start_per;
    private boolean dragging=false;
    private float currentValue;
    public VerticalSlider(){
        currentValue=0.0f;
        divThumb.addMouseDownHandler(new MouseDownHandler() {
            public void onMouseDown(MouseDownEvent event) {                
                onThumbMouseDown(event);
                event.getNativeEvent().stopPropagation();
                event.getNativeEvent().preventDefault();
            }
        });
    }
    private void setValue(float v){
        currentValue=v;        
    }
    public float getCurrentValue(){
        return currentValue;
    }
    private void onThumbMouseDown(MouseDownEvent e){
        dragging=true;
        first_y=e.getScreenY();
        try{
            String value=divThumb.getStyle().getTop();
            if(value.length()>0){
                if(value.endsWith("%")){
                    value=value.substring(0, value.length()-1);
                }
            }else{
                value="0";
            }
            start_per=Float.parseFloat(value);
        }catch(NumberFormatException ex){
            start_per=0.0f;
        }
        if(eventManager!=null && eventManager.hasEventHandlersForType(ChangeStartEvent.NAME)){
            ChangeStartEvent csevent=new ChangeStartEvent(this);
            fireEvent(csevent);
        }
        mousemoveHandleReg=Window.getDocument().addMouseMoveHandler(new MouseMoveHandler() {
            public void onMouseMove(MouseMoveEvent event) {
                event.getNativeEvent().stopPropagation();
                event.getNativeEvent().preventDefault();
                int delta=first_y-event.getScreenY();
                float change=(delta/divContainer.getClientHeight())*100;
                float new_value=start_per-change;
                float thumb_per=(divThumb.getOffsetHeight()/divContainer.getClientHeight())*100;
                if(new_value<=0){
                    new_value=0.0f;
                }
                if(new_value>(100.0-thumb_per)){
                    new_value=100.0f-thumb_per;
                }
                divThumb.getStyle().setTop(""+(new_value)+"%");
                setValue((new_value/(100.0f-thumb_per))*100);
                if(eventManager!=null && eventManager.hasEventHandlersForType(ChangeEvent.NAME)){
                    ChangeEvent ceevent=new ChangeEvent(this);
                    fireEvent(ceevent);
                }
            }
        });
        mouseupHandleReg=Window.getDocument().addMouseUpHandler(new MouseUpHandler() {
            public void onMouseUp(MouseUpEvent event) {
                if(eventManager!=null && eventManager.hasEventHandlersForType(ChangeEndEvent.NAME)){
                    ChangeEndEvent ceevent=new ChangeEndEvent(this);
                    fireEvent(ceevent);
                }
                mousemoveHandleReg.removeHandler();
                mouseupHandleReg.removeHandler();
                dragging=false;
            }
        });
    }


}
